package com.anmong.parser.service;

import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

@Service
public class NovelFormattingServiceBack {

    // 定义用于换行的标点符号集合 (不包含开引号 ‘“’)
    private static final Set<Character> PUNCTUATION_BREAK_POINTS = new HashSet<>(
            Arrays.asList('。', '，', '！', '？', '；', '…', '”', '』'));

    public String format(String novelText) {
        if (novelText == null || novelText.isEmpty()) {
            return "";
        }

        // 步骤 1: 预处理文本。移除所有原文的换行和段首缩进，
        // 将所有空白字符（包括空格、制表符等）统一成单个空格，最后去除首尾空格。
        // 这会创建一个干净、连续的文本流，便于处理。
        String continuousText = novelText.trim().replaceAll("[\\s　]+", " ");

        int totalLength = continuousText.length();
        int part1EndIndex = (int) (totalLength * 0.1);
        int part2EndIndex = (int) (totalLength * 0.5);

        StringBuilder formattedText = new StringBuilder();
        int cursor = 0;

        while (cursor < totalLength) {
            // 步骤 2: 根据当前光标位置，确定本行的长度规则
            int minLineLength, maxLineLength;
            if (cursor < part1EndIndex) {
                minLineLength = 5;
                maxLineLength = 10;
            } else if (cursor < part2EndIndex) {
                minLineLength = 10;
                maxLineLength = 30;
            } else {
                minLineLength = 30;
                maxLineLength = 50;
            }

            // 如果剩余文本已经不足以构成一个长行，则直接全部输出，结束循环
            if (totalLength - cursor <= maxLineLength) {
                formattedText.append(continuousText.substring(cursor));
                break;
            }

            // 步骤 3: 寻找最佳断点
            int breakPoint = -1;

            // 首先，在[min, max]这个理想区间内，从后往前寻找一个标点
            int searchLimit = Math.min(cursor + maxLineLength, totalLength - 1);
            for (int i = searchLimit; i > cursor + minLineLength; i--) {
                if (PUNCTUATION_BREAK_POINTS.contains(continuousText.charAt(i))) {
                    breakPoint = i;
                    break;
                }
            }

            // 如果在理想区间没找到，就必须向后查找，找到第一个出现的标点为止
            // 这是为了保证【绝不硬截断】
            if (breakPoint == -1) {
                for (int i = searchLimit + 1; i < totalLength; i++) {
                    if (PUNCTUATION_BREAK_POINTS.contains(continuousText.charAt(i))) {
                        breakPoint = i;
                        break;
                    }
                }
            }

            int endOfLine;
            if (breakPoint != -1) {
                // 如果找到了标点，断点就在标点之后
                endOfLine = breakPoint + 1;
            } else {
                // 如果到最后都没找到任何标点，说明剩余全是文本，直接输出
                endOfLine = totalLength;
            }

            // 步骤 4: 截取并清理行
            String line = continuousText.substring(cursor, endOfLine).trim(); // trim()移除因合并产生的行首空格
            if (!line.isEmpty()) {
                formattedText.append(line).append("\n");
            }
            cursor = endOfLine;
        }

        return formattedText.toString();
    }
}